package com.yenlien.traceyun.breed.service;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import com.yenlien.traceyun.business.interceptor.UserAuthUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;
import com.yenlien.traceyun.breed.dao.BreedDao;
import com.yenlien.traceyun.breed.dao.BreedDetailDao;
import com.yenlien.traceyun.breed.dao.OutDao;
import com.yenlien.traceyun.breed.dao.OutDetailDao;
import com.yenlien.traceyun.breed.entity.Breed;
import com.yenlien.traceyun.breed.entity.BreedDetail;
import com.yenlien.traceyun.breed.entity.Out;
import com.yenlien.traceyun.breed.entity.OutDetail;
import com.yenlien.traceyun.webase.exception.BusinessException;

@Service
public class OutService {
    @Autowired
    private OutDao outDao;
    @Autowired
    private BreedDao breedDao;
    @Autowired
    private OutDetailDao outDetailDao;
    @Autowired
    private BreedDetailDao breedDetailDao;
    @Autowired
    private JdbcTemplate jdbc;

    public Page<Out> findByList(final Out out) {
        Pageable pageable = PageRequest.of(out.getPage(), out.getPageSize(), Sort.Direction.DESC, ("createtime"));
        return outDao.findAll(new Specification<Out>() {
            private static final long serialVersionUID = -1396496630802017658L;

            @Override
            public Predicate toPredicate(Root<Out> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Path<String> breedId = root.get("breedId");
                Path<String> customer = root.get("customer");
                Path<String> outBatch = root.get("outBatch");
                //构造查询条件
                List<Predicate> list = new ArrayList<Predicate>();
                if (!StringUtils.isEmpty(out.getBreedId())) {
                    list.add(cb.equal(breedId, out.getBreedId()));
                }
                Predicate[] predicateA = new Predicate[list.size()];
                Predicate predicateAnd = cb.and(list.toArray(predicateA));

                if (StringUtils.isNotEmpty(out.getCustomer())) {
                    List<Predicate> list2 = new ArrayList<>();
                    list2.add(cb.like(customer, "%" + out.getCustomer() + "%"));
                    list2.add(cb.like(outBatch, "%" + out.getOutBatch() + "%"));
                    Predicate[] predicateO = new Predicate[list2.size()];
                    Predicate predicateOr = cb.or(list2.toArray(predicateO));
                    return query.where(predicateAnd, predicateOr).getRestriction();
                } else {
                    return predicateAnd;
                }
            }
        }, pageable);
    }

    @Transactional
    public void save(Out out) {
        List<OutDetail> outDetailList = out.getOutDetailList();
        if (outDetailList == null) {
            throw new BusinessException("A0001", "出场数量不能为0");
        }
        out.setOutNumber(outDetailList.size());

        //修改出场数量
        Breed breed = breedDao.findById(out.getBreedId());
        if (breed == null) {
            throw new BusinessException("A0001", "养殖批号不存在");
        }

        breed.setOutNumber(breed.getOutNumber() + outDetailList.size());
        breed.setSurplusNumber(breed.getSurplusNumber() - outDetailList.size());
        breedDao.save(breed);

        outDao.save(out);

        //修改出场编码
        List<BreedDetail> breedDetailList = breedDetailDao.findByTypeAndCodeList(out.getType(), out.getCodeList());
        for (BreedDetail breedDetail : breedDetailList) {
            breedDetail.setIsOut(1);
        }
        breedDetailDao.saveAll(breedDetailList);

        //记录出场详情
        String sql = "insert into t_breed_out_detail (id,last_step,out_id,seed_name,breed_batch,type,code,sex,company_id) values (?,?,?,?,?,?,?,?,?)";
        List<Object[]> batchArgs = new ArrayList<Object[]>();
        for (OutDetail outDetail : outDetailList) {
            batchArgs.add(new Object[]{UUID.randomUUID().toString().replaceAll("-", ""), out.getLastStep(), out.getId(), outDetail.getSeedName(),
                    outDetail.getBreedBatch(), outDetail.getType(), outDetail.getCode(), outDetail.getSex(), UserAuthUtil.getLoginUser().getCompanyId()});
        }
        jdbc.batchUpdate(sql, batchArgs);
    }

    public Out findById(String id) {
        Out out = outDao.findById(id);
//		if (out == null) {
//			throw new BusinessException("A0001", "数据有误");
//		}
//		out.setOutDetailList(outDetailDao.findByOutId(id));
        return out;
    }

    public BreedDetail findByTypeAndCode(JSONObject params) {
        BreedDetail breedDetail = breedDetailDao.findBreedDetail(params.getString("type"), params.getString("code"), 0, params.getString("batch"));
        if (breedDetail == null) {
            throw new BusinessException("A0001", "编码有误或者此编码已经出场");
        }
        return breedDetail;
    }
}
